#include "CanModule.h"
CanModule::CanModule(const std::string &interface)
{
    // 初始化变量
    m_fd = -1;
    memset(&ifr, 0, sizeof(ifr));
    memset(&can_addr, 0, sizeof(can_addr));
    memset(&frame, 0, sizeof(frame));

    // 打开套接字
    m_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    if (m_fd < 0)
    {
        perror("socket error");
        exit(EXIT_FAILURE);
    }

    // 设置接口名称
    strcpy(ifr.ifr_name, interface.c_str());
    if (ioctl(m_fd, SIOCGIFINDEX, &ifr) < 0)
    {
        perror("ioctl error");
        close(m_fd);
        exit(EXIT_FAILURE);
    }

    // 设置CAN地址
    can_addr.can_family = AF_CAN;
    can_addr.can_ifindex = ifr.ifr_ifindex;

    // 绑定套接字到CAN接口
    if (bind(m_fd, (struct sockaddr *)&can_addr, sizeof(can_addr)) < 0)
    {
        perror("bind error");
        close(m_fd);
        exit(EXIT_FAILURE);
    }
    int loopback = 1;
    if (setsockopt(m_fd, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback)) < 0)
    {
    perror("setsockopt CAN_RAW_LOOPBACK error");
    close(m_fd);
    exit(EXIT_FAILURE);
    }
}

CanModule::~CanModule()
{
    if (m_fd >= 0)
    {
        close(m_fd);
    }
}

// 写CAN数据
void CanModule::write_message(uint32_t canId, char *buf, size_t length)
{
    // 配置帧
    memset(&frame, 0, sizeof(struct can_frame));
    frame.can_id = canId;            // 设置CAN ID
    frame.can_dlc = length;          // 设置数据长度
    memcpy(frame.data, buf, length); // 复制数据
    printf("m_fd=%d\n",m_fd);
    // 写入数据
   int ret = write(m_fd, &frame, sizeof(frame)); //发送数据
    if(sizeof(frame) != ret) { //如果ret不等于帧长度，就说明发送失败
        perror("write error");
    }
}// 写CAN数据
void CanModule::write_message_frame(can_frame frame)
{
   int ret = write(m_fd, &frame, sizeof(frame)); //发送数据
    if(sizeof(frame) != ret) { //如果ret不等于帧长度，就说明发送失败
        perror("write error");
    }
}

// 设置CAN过滤规则
void CanModule::setFilter(uint32_t canId, uint32_t mask)
{
    struct can_filter rfilter;

    rfilter.can_id = canId;
    rfilter.can_mask = mask;

    // 设置过滤规则
    if (setsockopt(m_fd, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)) < 0)
    {
        perror("setsockopt error");
    }
    else
    {
        std::cout << "Filter set: CAN ID 0x" << std::hex << canId << ", Mask 0x" << mask << std::dec << std::endl;
    }
}


void CanModule::print_frame(can_frame& frame)
{
    
        /* 校验是否接收到错误帧 */
    if (frame.can_id & CAN_ERR_FLAG)
    {
        printf("Error frame!\n");
    }
    /* 校验帧类型：数据帧还是远程帧 */
    if (frame.can_id & CAN_RTR_FLAG)
    {
        printf("remote request\n");
    }

    /* 打印数据长度 */
    printf("11 [%d] ", frame.can_dlc);

    /* 打印数据 */
    for (int i = 0; i < frame.can_dlc; i++)
        printf("%02x ", frame.data[i]);
    printf("\n");
}